package com.qianfeng.smartplatform.event.listeners;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import com.qianfeng.smartplatform.event.LoginEvent;
import com.qianfeng.smartplatform.pojo.SysLogininfor;
import com.qianfeng.smartplatform.pojo.SysUserOnline;
import com.qianfeng.smartplatform.service.SysUserOnlineService;
import com.qianfeng.smartplatform.service.SysUserService;
import com.qianfeng.smartplatform.service.UserLoginlogService;
import com.qianfeng.smartplatform.utils.RequestUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Created by Jackiechan on 2022/5/26 10:18
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */
@Component
//@EnableAsync//开启异步
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class LoginListener {

    private UserLoginlogService userLoginlogService;

    private SysUserService sysUserService;

    private SysUserOnlineService sysUserOnlineService;

    @Autowired
    public void setSysUserOnlineService(SysUserOnlineService sysUserOnlineService) {
        this.sysUserOnlineService = sysUserOnlineService;
    }

    @Autowired
    public void setSysUserService(SysUserService sysUserService) {
        this.sysUserService = sysUserService;
    }

    @Autowired
    public void setUserLoginlogService(UserLoginlogService userLoginlogService) {
        this.userLoginlogService = userLoginlogService;
    }

    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    public void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor) {
        this.threadPoolExecutor = threadPoolExecutor;
    }

    @EventListener
    //@Async//异步执行,也就是新开一个线程
    public void onEvent(LoginEvent event) {
        System.err.println("收到了一个登录的事件");
        //获取到当前是谁在登录
        String username = event.getUsername();
        //springmvc通过threadlocal帮我们保存了一下请求对象,这样我们就不需要在方法的参数中传递request,减少接口污染的情况
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取登录数据,比如ip ,系统,浏览器等信息
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String seesionID = request.getSession().getId();
        //获取到操作系统和浏览器的信息
        Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);
        //获取到ip
        String ip = RequestUtil.getRemoteHost(request);
        Date processDate = new Date();//当前的处理时间
        //在新线程中执行以下操作
        CompletableFuture.runAsync(() -> {
            //获取到登录的ip所在的地区
            String locationByIp = RequestUtil.getLocationByIp(ip);
            //创建保存日志的对象
            SysLogininfor sysLogininfor = new SysLogininfor();
            //设置登录的用户名
            sysLogininfor.setLoginName(username);
            //设置操作系统和浏览器
            sysLogininfor.setBrowser(osAndBrowserInfo.get("browser"));
            sysLogininfor.setOs(osAndBrowserInfo.get("os"));
            //设置登录的时间
            sysLogininfor.setLoginTime(processDate);
            //设置登录的ip
            sysLogininfor.setIpaddr(ip);
            //设置登录地址
            sysLogininfor.setLoginLocation(locationByIp);

            switch (event.getType()) {
                case SUCCESS:
                    sysLogininfor.setMsg("登录成功");
                    sysLogininfor.setStatus("1");
                    break;
                case FAIL:
                    sysLogininfor.setMsg("用户名密码错误");
                    sysLogininfor.setStatus("0");
                    break;
            }

            SysUserOnline sysUserOnline = new SysUserOnline();
            //把我们上面的数据复制到sysUserOnline
            BeanUtils.copyProperties(sysLogininfor,sysUserOnline);
            sysUserOnline.setSessionId(seesionID);
            sysUserOnline.setStartTimestamp(processDate);
            sysUserOnline.setExpireTime(30L);
            //添加登录的日志,每次登录都会添加一条新的数据
            userLoginlogService.addLoginLog(sysLogininfor);
            //更新在线用户的数据,每个用户只有一条
            sysUserOnlineService.addOrUpdateOnline(sysUserOnline);

        }, threadPoolExecutor);


        switch (event.getType()) {
            case SUCCESS:
                //更新用户的登录时间和ip
                CompletableFuture.runAsync(() -> {
                    sysUserService.updateLogin(username, processDate, ip);
                }, threadPoolExecutor);
                break;
        }

    }
}
